/* 
 * File:   smtp_delivery.h
 * Author: james
 *
 * Created on 2011年3月23日, 下午2:43
 */

#ifndef SMTP_DELIVERY_H
#define	SMTP_DELIVERY_H

#include <string>
#include <vector>
using namespace std;

enum smtp_status_t{
    SMTP_OK = 0,
    SMTP_RETRY = 400,
    SMTP_FAILED = 500
};

enum mx_status_t {
    MX_S_OK = 0,       //0 mail sent
    MX_S_TO_DOMAIN,    //1 invalid receipt mail address
    MX_S_TO_PAUSED,    //2 domain of receipt is currently paused
    MX_S_TO_MX,        //3 cannot find MX for receipt's domain
    MX_S_TO_DOWN,      //4 MX of receipt is down
    MX_S_TO_FROZEN,    //5 MX of receipt is frozen (TCP timeout)
    MX_S_TO_USER,      //6 mail address is unknown to MX
    MX_S_FROM_DOMAIN,  //7 invalid sender mail address
    MX_S_SMTP_HELO,    //8 non-250 returned after HELO sent
    MX_S_SMTP_MAIL,    //9 non-250 returned after MAIL FROM sent
    MX_S_SMTP_RCPT,    //10 non-250 returned after RCPT TO sent
    MX_S_SMTP_DATA,    //11 non-354 returned after DATA sent
    MX_S_SMTP_DOT,     //12 non-250 returned after '.' sent
};

class smtp_delivery_t
{
public:
    smtp_delivery_t(const char* bind_ip = "");
    ~smtp_delivery_t();
    
    int send(
             const char* helo_host,
             const char* from,
             const char* to,
             const char* to_domain,
             long timeout,
             int msg_fd,
             vector<string>& mx);
    
    int send(
             const char* helo_host,
             const char* from,
             const char* to,
             const char* to_domain,
             long timeout,
             string& data,
             vector<string>& mx);
    
    int status();
    int smtp_code();
    const char* reason();
private:
    smtp_delivery_t(smtp_delivery_t&);
    smtp_delivery_t& operator=(smtp_delivery_t&);
    
    int connect_mx_i(vector<string>& mx_list);
    int read_socket_i(int sock, std::string & msg, int timeout);
    void set_status_i(smtp_status_t smtp_status, mx_status_t mx_status, const char* fmt, ...);
    int get_smtp_code_i(const string& response, string& reason);
    
private:
    string              m_bind_ip;
    int                 m_smtp_code;
    mx_status_t         m_mx_status;
    smtp_status_t       m_smtp_status;
    string              m_reason;
};

#endif	/* SMTP_DELIVERY_H */

